//
// Created by denglibin on 19-4-13.
//

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/wait.h>
#include<sys/types.h>;

/*
    waitpid()的作用和wait()一样，但它并不一定要等待第一个终止的子进程（它可以指定需要等待终止的子进程），它还有若干选项，如可提供一个非阻塞版本的 wait()功能，
也能支持作业控制。实际上，wait()函数只是 waitpid()函数的一个特例，在Linux 内部实现 wait()函数时直接调用的就是waitpid()函数

pid_t waitpid(pid_t pid, int *status,int options);
参数1：要回收的子进程的id
         pid>0时，只等待进程ID等于pid的子进程，不管其它已经有多少子进程运行结束退出了，只要指定的子进程还没有结束，waitpid就会一直等下去。

         pid=-1时，等待任何一个子进程退出，没有任何限制，此时waitpid和wait的作用一模一样。

         pid=0时，等待同一个进程组中的任何子进程，如果子进程已经加入了别的进程组，waitpid不会对它做任何理睬。

         pid<-1时，等待一个指定进程组中的任何子进程，这个进程组的ID等于pid的绝对值。
参数2：要回收的子进程的状态
参数3：是否阻塞
        options提供了一些额外的选项来控制waitpid，目前在Linux中只支持WNOHANG和WUNTRACED两个选项，这是两个常数，可以用"|"运算符把它们连接起来使用，比如：

        ret=waitpid(-1,NULL,WNOHANG | WUNTRACED);

        如果我们不想使用它们，也可以把options设为0，如：

        ret=waitpid(-1,NULL,0);

        如果使用了WNOHANG参数调用waitpid，即使没有子进程退出，它也会立即返回，不会像wait那样永远等下去
成功：返回清理掉的子进程的id，
失败：返回-1
waitpid的返回值比wait稍微复杂一些，一共有3种情况：

          1、当正常返回的时候，waitpid返回收集到的子进程的进程ID；

          2、如果设置了选项WNOHANG，而调用中waitpid发现没有已退出的子进程可收集，则返回0；

          3、如果调用中出错，则返回-1，这时errno会被设置成相应的值以指示错误所在；
*/
static int main_(int argc, char** argv)
{
    pid_t pc, pr;
    pc = fork();
    if(pc < 0)
    {
        printf("fork error");
    }
    else if(pc == 0) //子进程
    {
        sleep(10);
        exit(0);
    }
    /*父进程*/
    do{
        pr = waitpid(pc,NULL,WNOHANG); /* 回收指定进程 使用了WNOHANG参数，waitpid不会在这里等待 */
        if(pr == 0)
        {
            printf("no child exited");
        }
        sleep(2); //睡2秒再回收
    }while(pr==0); //没有回收到 继续循环

    //回收所有的子进程
    /*
     int n = 1;//子进程的个数
      do {
             if(waitpid(-1,NULL,WNOHANG) >0 ) //回收了一个子进程
             {
                 n--;
             }

         } while(n>0)
         */

    if(pr == pc)
    {
        printf("successfully get child ");
    }
    else
    {
        printf("some error occured");
    }
    return 0;
}

















